﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net;
using System.Web.Helpers;
using System.Web.Mvc;
using System.Xml;
using System.Xml.Linq;
using Google.GData.Photos;
using HopNguyenCms.App_Start;
using HopNguyenCms.Infrastructure;
using HopNguyenModel;
using HopNguyenModel.General;

namespace HopNguyenCms.Controllers
{
    public class WebsiteController : Controller
    {
        /// <summary>
        /// 1 : Download video
        /// 2 : Watch video
        /// 3 : Page
        /// 4 : Search
        /// </summary>

        readonly Content _content = new Content();

        [ValidateInput(false)]
        public ActionResult Index(string url)
        {
            var meta = "";
            if (!string.IsNullOrEmpty(url))
            {
                url = Server.HtmlEncode(url);
                url = CheckUrl(url);
                if (string.IsNullOrEmpty(url))
                    ViewBag.Error = "You enter invalid YouTube URL, Please correct it.";
                else
                {
                    var urls = YouTubeDownloader.GetYouTubeVideoUrls(url);
                    if (urls.Any())
                    {
                        var video = urls[0];
                        var alias = Helper.GetVideoIDFromUrl(url);
                        ViewBag.VideoID = alias;
                        ViewBag.Video = urls;
                        var videoLength = TimeSpan.FromSeconds(video.Length);
                        var time = "";
                        if (videoLength.Hours > 0)
                        {
                            time = String.Format("{0}:{1}:{2}", videoLength.Hours, videoLength.Minutes,
                                videoLength.Seconds);
                        }
                        else
                        {
                            time = String.Format("{0}:{1}", videoLength.Minutes, videoLength.Seconds);
                        }
                        ViewBag.Time = time;

                        meta = GenerateMeta.AutoGenerateMeta(1, null, video.VideoTitle, "", alias);
                    }
                    else
                    {
                        ViewBag.Error = "Video does not exist!";
                    }

                }
            }
            else
            {
                meta = GenerateMeta.AutoGenerateMeta(3);
            }
            ViewBag.Meta = meta;
            return View();
        }

        [ValidateInput(false)]
        public ActionResult Watch(string v)
        {
            var meta = "";
            var url = "https://www.youtube.com/watch?v=" + v;
            url = Server.HtmlEncode(url);
            var urls = YouTubeDownloader.GetYouTubeVideoUrls(url);
            if (urls.Any())
            {
                var video = urls[0];
                var alias = Helper.GetVideoIDFromUrl(url);
                ViewBag.VideoID = alias;
                ViewBag.Video = urls;
                var videoLength = TimeSpan.FromSeconds(video.Length);
                var time = "";
                if (videoLength.Hours > 0)
                {
                    time = String.Format("{0}:{1}:{2}", videoLength.Hours, videoLength.Minutes,
                        videoLength.Seconds);
                }
                else
                {
                    time = String.Format("{0}:{1}", videoLength.Minutes, videoLength.Seconds);
                }
                ViewBag.Time = time;
                meta = GenerateMeta.AutoGenerateMeta(1, null, video.VideoTitle, "", alias);
            }
            else
            {
                ViewBag.Error = "Video does not exist!";
                meta = GenerateMeta.AutoGenerateMeta(3);
            }
            ViewBag.Meta = meta;
            return View("Index");
        }

        [HttpPost]
        [ValidateInput(false)]
        public ActionResult SearchVideo(string url)
        {
            if (!string.IsNullOrEmpty(url))
            {
                url = CheckUrl(url);
                url = Server.HtmlEncode(url);
                if (string.IsNullOrEmpty(url))
                    ViewBag.Error = "You enter invalid YouTube URL, Please correct it.";
                else
                {
                    var urls = YouTubeDownloader.GetYouTubeVideoUrls(url);
                    if (urls.Any())
                    {
                        var video = urls[0];
                        var alias = Helper.GetVideoIDFromUrl(url);
                        ViewBag.VideoID = alias;
                        ViewBag.Video = urls;
                        var videoLength = TimeSpan.FromSeconds(video.Length);
                        var time = "";
                        if (videoLength.Hours > 0)
                        {
                            time = String.Format("{0}:{1}:{2}", videoLength.Hours, videoLength.Minutes,
                                videoLength.Seconds);
                        }
                        else
                        {
                            time = String.Format("{0}:{1}", videoLength.Minutes, videoLength.Seconds);
                        }
                        ViewBag.Time = time;
                        //add audit download
                        //CreateYoutube(video.VideoTitle, alias, time);
                    }
                    else
                    {
                        ViewBag.Error = "Video does not exist!";
                    }

                }
            }
            return PartialView("Patial/General/_YoutubeResult");
        }

        static string CheckUrl(string url)
        {
            if (url.StartsWith("https://")) url = "http://" + url.Substring(8);
            else if (!url.StartsWith("http://")) url = "http://" + url;

            url = url.Replace("youtu.be/", "youtube.com/watch?v=");
            url = url.Replace("www.youtube.com", "youtube.com");

            if (url.StartsWith("http://youtube.com/v/"))
                url = url.Replace("youtube.com/v/", "youtube.com/watch?v=");
            else if (url.StartsWith("http://youtube.com/watch#"))
                url = url.Replace("youtube.com/watch#", "youtube.com/watch?");

            return !url.StartsWith("http://youtube.com/watch") ? null : url;
        }

        [ValidateInput(false)]
        public void CreateYoutube(string title, string alias, string time)
        {
            if (Request.UserAgent == "Googlebot/2.1 (+http://www.googlebot.com/bot.html)")
            {
                return;
            }
            var db = new HopNguyenEntities();
            title = Server.HtmlDecode(title);
            var obj = db.Contents.FirstOrDefault(a => a.Alias.Equals(alias));
            if (obj != null)
            {
                obj.Download = obj.Download == null ? 1 : obj.Download + 1;
                obj.DownloadDate = DateTime.Now;
                db.SaveChanges();
                return;
            }
            var imageShare = "http://i3.ytimg.com/vi/" + alias + "/0.jpg";
            //try
            //{
            //    imageShare = UploadImageShare(alias);
            //}
            //catch
            //{
            //    imageShare = "http://i3.ytimg.com/vi/" + alias + "/0.jpg";
            //}

            db.Contents.Add(new Content()
            {
                Name = title,
                Alias = alias,
                Image = "http://i3.ytimg.com/vi/" + alias + "/0.jpg",
                Summary = time,
                GroupId = 2,
                CreateDate = DateTime.Now,
                DownloadDate = DateTime.Now,
                TypeId = 39,
                Download = 1,
                Status = true,
                ImageShare = imageShare
            });
            db.SaveChanges();
        }

        public static string formatSize(object value)
        {
            string s = ((Size)value).Height >= 720 ? " HD" : "";
            if (value is Size) return ((Size)value).Width + " x " + ((Size)value).Height + s;
            return "";
        }

        public static string formatSizeBinary(Int64 size, Int32 decimals = 2)
        {
            string[] sizes = { "Bytes", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB" };
            double formattedSize = size;
            Int32 sizeIndex = 0;
            while (formattedSize >= 1024 & sizeIndex < sizes.Length)
            {
                formattedSize /= 1024;
                sizeIndex += 1;
            }
            return string.Format("{0} {1}", Math.Round(formattedSize, decimals).ToString(), sizes[sizeIndex]);
        }

        public ActionResult Contact()
        {
            ViewBag.Meta = GenerateMeta.AutoGenerateMeta(3, null, null, null, null, "contact");
            return View();
        }

        [HttpPost]
        public ActionResult SendContact(string name, string email, string message)
        {
            var str = "<div><strong>Họ Tên</strong>: " + name + "<br /><strong>Email</strong>: " + email
                + "<br /><strong>Nội dung</strong>: " + message + "</div>";
            Email.SendMail("Thư liên hệ từ : " + name + " - " + Request.Url.Host, str);
            return Redirect("/contact.html?msg=true");
        }

        public ActionResult PrivacyPolicy()
        {
            return View();
        }

        public ActionResult WatchVideo(string alias)
        {
            var video = _content.GetByAlias(alias);
            ViewBag.Meta = GenerateMeta.AutoGenerateMeta(2, video);
            return View(video);
        }

        public PartialViewResult OtherVideoDownload()
        {
            return PartialView("OtherVideoDownload");
        }

        public ActionResult SearchContent(string q)
        {
            ViewBag.Q = q;
            ViewBag.Meta = GenerateMeta.AutoGenerateMeta(4, null, null, null, null, null, q);
            return View();
        }
        
        public ActionResult Popular(string sort, int p = 1)
        {
            const int itemShow = 21;
            var db = new HopNguyenEntities();
            var queryString = !string.IsNullOrEmpty(sort) ? "&sort=" + sort : "";
            var url = Request.RawUrl.Split('?')[0];
            ViewBag.Page = p;
            ViewBag.Sort = sort;
            var videos = db.PaginationContent(p, itemShow, (string.IsNullOrEmpty(sort) ? "id" : sort));
            ViewBag.Pagination = db.Pagination(p, 4, itemShow, queryString, url).FirstOrDefault();
            return View(videos);
        }

        public ActionResult HowToDownLoad()
        {
            ViewBag.Meta = GenerateMeta.AutoGenerateMeta(3, null, null, null, null, "how-to-download");
            return View();
        }
        
        public ActionResult Error()
        {
            ViewBag.Meta = GenerateMeta.AutoGenerateMeta(3, null, null, null, null, "error");
            return View();
        }

        public ActionResult Donate()
        {
            ViewBag.Meta = GenerateMeta.AutoGenerateMeta(3, null, null, null, null, "donate");
            return View();
        }

        public string UploadImageShare(string alias)
        {
            var webClient = new WebClient();
            var path = Server.MapPath("~/upload/images/" + alias + ".jpg");
            webClient.DownloadFile("http://i3.ytimg.com/vi/" + alias + "/hqdefault.jpg", path);
            var image = new WebImage(path);
            image.AddImageWatermark(Server.MapPath("~/frontend/img/play2.png"), 73, 72, "Center", "Middle");
            image.Save(Server.MapPath("~/upload/shared/" + alias + ".jpg"));
            System.IO.File.Delete(path);

            var oService = new PicasaService("web-application-study");
            oService.setUserCredentials("hopnguyenstorage@gmail.com", "qq101991");
            var pathNew = Server.MapPath("~/upload/shared/" + alias + ".jpg");

            var fileInfo = new FileInfo(pathNew);
            var fileStream = fileInfo.OpenRead();
            var postUri = new Uri(PicasaQuery.CreatePicasaUri("default", "default"));
            var entry = (PicasaEntry)oService.Insert(postUri, fileStream, "image/jpeg", alias + ".jpg");
            fileStream.Close();
            System.IO.File.Delete(pathNew);
            return entry.Media.Content.Url;
        }

        public ActionResult AutoGenSitemap()
        {
            var ns = XNamespace.Get("http://www.sitemaps.org/schemas/sitemap/0.9");
            XElement urlset = null;
            var siteMapDocument = new XDocument(urlset = new XElement(ns + "urlset"));
            urlset.Add(new XElement(ns + "url",
                new XElement(ns + "loc", "http://www.getlinkyoutube.com/"),
                new XElement(ns + "lastmod", DateTime.Now),
                new XElement(ns + "changefreq", "daily"),
                new XElement(ns + "priority", "1.0")
                ));
            var urls = new List<string>
            {
                "http://www.getlinkyoutube.com/how-to-download.html",
                "http://www.getlinkyoutube.com/popular.html",
                "http://www.getlinkyoutube.com/donate.html",
                "http://www.getlinkyoutube.com/contact.html"
            };

            foreach (var item in urls)
            {
                urlset.Add(new XElement
                (ns + "url",
                new XElement(ns + "loc", item),
                new XElement(ns + "changefreq", "weekly"),
                new XElement(ns + "priority", "0.8")
                ));
            }
            var contents = _content.GetAllAlias(2);
            for (var i = 0; i < Math.Ceiling(contents.Count / (float)18); i++)
            {
                urlset.Add(new XElement
                (ns + "url",
                new XElement(ns + "loc", "http://www.getlinkyoutube.com/popular.html?p=" + (i + 1)),
                new XElement(ns + "changefreq", "daily"),
                new XElement(ns + "priority", "0.8")
                ));
            }
            foreach (var item in contents)
            {
                urlset.Add(new XElement
                (ns + "url",
                new XElement(ns + "loc", "http://www.getlinkyoutube.com/video/" + item + ".html"),
                new XElement(ns + "changefreq", "hourly"),
                new XElement(ns + "priority", "0.6")
                ));
                urlset.Add(new XElement
                (ns + "url",
                new XElement(ns + "loc", "http://www.getlinkyoutube.com/watch?v=" + item),
                new XElement(ns + "changefreq", "hourly"),
                new XElement(ns + "priority", "0.5")
                ));
            }

            siteMapDocument.Save(String.Format("{0}\\{1}", AppDomain.CurrentDomain.BaseDirectory, "sitemap.xml"));
            return Redirect("http://www.google.com/webmasters/tools/ping?sitemap=http://www.getlinkyoutube.com/sitemap.xml");
        }
    }
}
